package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.core.exception.BizException;
import com.eastfair.venueservice.dao.StorageInfoMapper;
import com.eastfair.venueservice.dto.StorageInfoDTO;
import com.eastfair.venueservice.dto.StorageInfoPageQuery;
import com.eastfair.venueservice.entity.StorageInfo;
import com.eastfair.venueservice.enums.LogisticsExamineStateEnum;
import com.eastfair.venueservice.service.StorageInfoService;
import com.eastfair.venueservice.vo.StorageInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 智慧物流 仓储服务
 *
 * @author Du Xiaobo
 * @date 2023/5/8 18:18
 */
@Service
@Slf4j
public class StorageInfoServiceImpl extends SuperServiceImpl<StorageInfoMapper, StorageInfo> implements StorageInfoService {
    @Override
    public Long saveStorageInfo(StorageInfoDTO dto) {
        log.info("新增仓储服务入参：dto={}", dto);
        StorageInfo info = new StorageInfo();
        BeanUtils.copyProperties(dto, info);
        info.setExamineState(LogisticsExamineStateEnum.APPLIED.getCode());
        save(info);
        log.info("新增仓储服务成功：model={}", info);
        return info.getId();
    }

    @Override
    public void updateStorageInfo(StorageInfoDTO dto) {
        log.info("修改仓储服务入参：dto={}", dto);
        StorageInfo one = lambdaQuery().eq(StorageInfo::getId, dto.getId()).one();
        if (Objects.isNull(one)) {
            throw BizException.wrap("修改的记录不存在");
        }
        StorageInfo info = new StorageInfo();
        BeanUtils.copyProperties(dto, info);
        updateById(info);
        log.info("修改仓储服务成功：model={}", info);
    }

    @Override
    public StorageInfoVo getStorageInfoById(Long id) {
        StorageInfo info = lambdaQuery().eq(StorageInfo::getId, id).one();
        if (Objects.isNull(info)) {
            throw BizException.wrap("查询记录不存在,id={}", id);
        }
        StorageInfoVo vo = new StorageInfoVo();
        BeanUtils.copyProperties(info, vo);
        return vo;
    }

    @Override
    public Page<StorageInfoVo> listStorageInfo(PageParams<StorageInfoPageQuery> pageParams) {
        log.info("listStorageInfo - 查询仓储服务列表VO, pageParams={}", pageParams);
        Page<StorageInfo> pageParam = pageParams.buildPage();
        QueryWrapper<StorageInfo> queryWrapper = createStorageInfoQueryWrapper(pageParams);
        Page<StorageInfo> page = page(pageParam, queryWrapper);
        Page<StorageInfoVo> voPage = new Page<>();
        BeanUtil.copyProperties(page, voPage);
        List<StorageInfo> list = page.getRecords();
        if (list == null || list.isEmpty()) {
            return voPage;
        }
        List<StorageInfoVo> voList = list
                .stream()
                .map(load -> BeanUtil.toBean(load, StorageInfoVo.class))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    private QueryWrapper<StorageInfo> createStorageInfoQueryWrapper(PageParams<StorageInfoPageQuery> params) {
        StorageInfoPageQuery model = params.getModel();
        QueryWrapper<StorageInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(StrUtil.isNotBlank(model.getExhibitionName()), StorageInfo::getExhibitionName, model.getExhibitionName())
                .eq(StrUtil.isNotBlank(model.getPrincipalType()), StorageInfo::getPrincipalType, model.getPrincipalType())
                // 审核状态
                .eq(StrUtil.isNotBlank(model.getExamineState()), StorageInfo::getExamineState, LogisticsExamineStateEnum.valueOf(model.getExamineState()).getCode())
        ;
        if (StrUtil.isNotBlank(params.getOrder())) {
            if (StrUtil.isNotBlank(params.getOrder())) {
                queryWrapper.orderBy(false, "ASC".equals(params.getSort().toUpperCase()), params.getOrder());
            }
        }
        return queryWrapper;
    }

    @Override
    public Boolean examine(StorageInfoDTO dto) {
        log.info("examine - 仓储服务审核入参, dto={}", dto);
        LogisticsExamineStateEnum stateEnum = LogisticsExamineStateEnum.valueOf(dto.getExamineState());
        LambdaUpdateChainWrapper<StorageInfo> wrapper = lambdaUpdate()
                .set(StorageInfo::getExamineState, stateEnum.getCode())
                .set(StorageInfo::getExamineTime, LocalDateTime.now())
                .set(StorageInfo::getExamineReason, dto.getExamineReason())
                .eq(StorageInfo::getId, dto.getId());

        // 判断审核状态
        if (LogisticsExamineStateEnum.APPROVED.equals(stateEnum)) {
            // 填充实际值
            wrapper.set(StorageInfo::getActualVolume, dto.getActualVolume())
                    // todo 计算实际费用
                    .set(StorageInfo::getActualVolume, BigDecimal.ZERO)
                    .set(StorageInfo::getActualInputDate, LocalDateTime.now())
                    .set(StorageInfo::getActualOutputDate,LocalDateTime.now())
                    .set(StorageInfo::getActualCost,BigDecimal.ZERO);

            // todo 生成物流订单
            // todo 同步支付系统
        }
        update(wrapper);
        log.info("examine - 装卸服务审核完成");
        return true;
    }
}
